package cn.chiship.framework.upms.biz.base.service.impl;

import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.upms.biz.base.service.CaptchaService;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseCacheConstants;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @author lijian 图形验证码
 */
@Service
public class CaptchaServiceImpl implements CaptchaService {

	@Resource
	private RedisService redisService;

	@Override
	public void getCaptchaCodeImage(HttpServletResponse response) {
		try {
			outputCaptcha(response);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public BaseResult getCaptchaCodeText() {
		String randomString = getRandomString().toUpperCase();
		redisService.hset(CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_CAPTCHA_PREFIX), randomString,
				randomString, 3600);
		return BaseResult.ok(randomString);
	}

	@Override
	public BaseResult verification(String code) {
		code = code.toUpperCase();
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_CAPTCHA_PREFIX);
		if (redisService.hget(key, code) == null) {
			return BaseResult.error("验证码错误");
		}
		redisService.hdel(key, code);
		return BaseResult.ok();
	}

	private static final char[] CHARS = { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
			'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

	private static Random random = new Random();

	private static final int CHARS_LENGTH = 4;

	private static final int RECT_NUMBER = 100;

	private static String getRandomString() {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < CHARS_LENGTH; i++) {
			builder.append(CHARS[random.nextInt(CHARS.length)]);
		}
		return builder.toString();
	}

	private static Color getRandomColor() {
		return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
	}

	private static Color getReverseColor() {
		return new Color(255, 255, 255);
	}

	public void outputCaptcha(HttpServletResponse response) throws IOException {

		response.setDateHeader("Expires", 0);
		response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
		response.addHeader("Cache-Control", "post-check=0, pre-check=0");
		response.setHeader("Pragma", "no-cache");
		response.setContentType("image/jpeg");

		String randomString = getRandomString().toUpperCase();
		redisService.hset(CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_CAPTCHA_PREFIX), randomString,
				randomString, 3600);
		int width = 100;
		int height = 35;
		Color color = getRandomColor();
		Color reverse = getReverseColor();

		BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = bi.createGraphics();
		g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
		g.setColor(reverse);
		g.fillRect(0, 0, width, height);
		g.setColor(color);
		g.drawString(randomString, 18, 20);
		for (int i = 0, n = random.nextInt(RECT_NUMBER); i < n; i++) {
			g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
		}

		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(bi, "png", out);
		out.flush();
	}

}
